1. Project Clover database Tue Apr 11 2023 12:41:06 EDT
  2. Package org.joda.time

File DateTimeUtils.java

 

Coverage histogram

../../../img/srcFileCovDistChart9.png
50% of files have more coverage

Code metrics

44
102
30
5
626
215
55
0.54
3.4
6
1.83

Classes

Class Line # Actions
DateTimeUtils 39 97 0% 50 33
0.801204880.1%
DateTimeUtils.MillisProvider 545 0 - 0 0
-1.0 -
DateTimeUtils.SystemMillisProvider 559 1 0% 1 0
1.0100%
DateTimeUtils.FixedMillisProvider 573 2 0% 2 0
1.0100%
DateTimeUtils.OffsetMillisProvider 601 2 0% 2 0
1.0100%
 

Contributing tests

This file is covered by 3258 tests. .

Source view

1    /*
2    * Copyright 2001-2013 Stephen Colebourne
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package org.joda.time;
17   
18    import java.lang.reflect.Method;
19    import java.text.DateFormatSymbols;
20    import java.util.Collections;
21    import java.util.HashMap;
22    import java.util.LinkedHashMap;
23    import java.util.Locale;
24    import java.util.Map;
25    import java.util.concurrent.atomic.AtomicReference;
26   
27    import org.joda.time.chrono.ISOChronology;
28   
29    /**
30    * DateTimeUtils provide public utility methods for the date-time library.
31    * <p>
32    * DateTimeUtils uses shared static variables which are declared as volatile
33    * for thread-safety. These can be changed during the lifetime of the application
34    * however doing so is generally a bad idea.
35    *
36    * @author Stephen Colebourne
37    * @since 1.0
38    */
 
39    public class DateTimeUtils {
40   
41    /**
42    * The singleton instance of the system millisecond provider.
43    */
44    public static final MillisProvider SYSTEM_MILLIS_PROVIDER = new SystemMillisProvider();
45   
46    /**
47    * The millisecond provider currently in use.
48    */
49    private static volatile MillisProvider cMillisProvider = SYSTEM_MILLIS_PROVIDER;
50    /**
51    * The default names.
52    * This is lazily initialized to reduce risks of race conditions at startup.
53    */
54    private static final AtomicReference<Map<String, DateTimeZone>> cZoneNames =
55    new AtomicReference<Map<String, DateTimeZone>>();
56   
57    /**
58    * Restrictive constructor
59    */
 
60  1 toggle protected DateTimeUtils() {
61  1 super();
62    }
63   
64    //-----------------------------------------------------------------------
65   
66    /**
67    * Gets the current time in milliseconds.
68    * <p>
69    * By default this returns <code>System.currentTimeMillis()</code>.
70    * This may be changed using other methods in this class.
71    *
72    * @return the current time in milliseconds from 1970-01-01T00:00:00Z
73    */
 
74  10603 toggle public static final long currentTimeMillis() {
75  10603 return cMillisProvider.getMillis();
76    }
77   
78    /**
79    * Resets the current time to return the system time.
80    * <p>
81    * This method changes the behaviour of {@link #currentTimeMillis()}.
82    * Whenever the current time is queried, {@link System#currentTimeMillis()} is used.
83    *
84    * @throws SecurityException if the application does not have sufficient security rights
85    */
 
86  2942 toggle public static final void setCurrentMillisSystem() throws SecurityException {
87  2942 checkPermission();
88  2942 cMillisProvider = SYSTEM_MILLIS_PROVIDER;
89    }
90   
91    /**
92    * Sets the current time to return a fixed millisecond time.
93    * <p>
94    * This method changes the behaviour of {@link #currentTimeMillis()}.
95    * Whenever the current time is queried, the same millisecond time will be returned.
96    *
97    * @param fixedMillis the fixed millisecond time to use
98    * @throws SecurityException if the application does not have sufficient security rights
99    */
 
100  3072 toggle public static final void setCurrentMillisFixed(long fixedMillis) throws SecurityException {
101  3072 checkPermission();
102  3072 cMillisProvider = new FixedMillisProvider(fixedMillis);
103    }
104   
105    /**
106    * Sets the current time to return the system time plus an offset.
107    * <p>
108    * This method changes the behaviour of {@link #currentTimeMillis()}.
109    * Whenever the current time is queried, {@link System#currentTimeMillis()} is used
110    * and then offset by adding the millisecond value specified here.
111    *
112    * @param offsetMillis the fixed millisecond time to use
113    * @throws SecurityException if the application does not have sufficient security rights
114    */
 
115  2 toggle public static final void setCurrentMillisOffset(long offsetMillis) throws SecurityException {
116  2 checkPermission();
117  2 if (offsetMillis == 0) {
118  1 cMillisProvider = SYSTEM_MILLIS_PROVIDER;
119    } else {
120  1 cMillisProvider = new OffsetMillisProvider(offsetMillis);
121    }
122    }
123   
124    /**
125    * Sets the provider of the current time to class specified.
126    * <p>
127    * This method changes the behaviour of {@link #currentTimeMillis()}.
128    * Whenever the current time is queried, the specified class will be called.
129    *
130    * @param millisProvider the provider of the current time to use, not null
131    * @throws SecurityException if the application does not have sufficient security rights
132    * @since 2.0
133    */
 
134  2 toggle public static final void setCurrentMillisProvider(MillisProvider millisProvider) throws SecurityException {
135  2 if (millisProvider == null) {
136  1 throw new IllegalArgumentException("The MillisProvider must not be null");
137    }
138  1 checkPermission();
139  1 cMillisProvider = millisProvider;
140    }
141   
142    /**
143    * Checks whether the provider may be changed using permission 'CurrentTime.setProvider'.
144    *
145    * @throws SecurityException if the provider may not be changed
146    */
 
147  6017 toggle private static void checkPermission() throws SecurityException {
148  6017 SecurityManager sm = System.getSecurityManager();
149  6017 if (sm != null) {
150  0 sm.checkPermission(new JodaTimePermission("CurrentTime.setProvider"));
151    }
152    }
153   
154    //-----------------------------------------------------------------------
155   
156    /**
157    * Gets the millisecond instant from the specified instant object handling null.
158    * <p>
159    * If the instant object is <code>null</code>, the {@link #currentTimeMillis()}
160    * will be returned. Otherwise, the millis from the object are returned.
161    *
162    * @param instant the instant to examine, null means now
163    * @return the time in milliseconds from 1970-01-01T00:00:00Z
164    */
 
165  4315 toggle public static final long getInstantMillis(ReadableInstant instant) {
166  4315 if (instant == null) {
167  82 return DateTimeUtils.currentTimeMillis();
168    }
169  4233 return instant.getMillis();
170    }
171   
172    //-----------------------------------------------------------------------
173   
174    /**
175    * Gets the chronology from the specified instant object handling null.
176    * <p>
177    * If the instant object is <code>null</code>, or the instant's chronology is
178    * <code>null</code>, {@link ISOChronology#getInstance()} will be returned.
179    * Otherwise, the chronology from the object is returned.
180    *
181    * @param instant the instant to examine, null means ISO in the default zone
182    * @return the chronology, never null
183    */
 
184  3983 toggle public static final Chronology getInstantChronology(ReadableInstant instant) {
185  3983 if (instant == null) {
186  29 return ISOChronology.getInstance();
187    }
188  3954 Chronology chrono = instant.getChronology();
189  3954 if (chrono == null) {
190  1 return ISOChronology.getInstance();
191    }
192  3953 return chrono;
193    }
194   
195    //-----------------------------------------------------------------------
196   
197    /**
198    * Gets the chronology from the specified instant based interval handling null.
199    * <p>
200    * The chronology is obtained from the start if that is not null, or from the
201    * end if the start is null. The result is additionally checked, and if still
202    * null then {@link ISOChronology#getInstance()} will be returned.
203    *
204    * @param start the instant to examine and use as the primary source of the chronology
205    * @param end the instant to examine and use as the secondary source of the chronology
206    * @return the chronology, never null
207    */
 
208  39 toggle public static final Chronology getIntervalChronology(ReadableInstant start, ReadableInstant end) {
209  39 Chronology chrono = null;
210  39 if (start != null) {
211  33 chrono = start.getChronology();
212  6 } else if (end != null) {
213  5 chrono = end.getChronology();
214    }
215  39 if (chrono == null) {
216  1 chrono = ISOChronology.getInstance();
217    }
218  39 return chrono;
219    }
220   
221    //-----------------------------------------------------------------------
222   
223    /**
224    * Gets the chronology from the specified interval object handling null.
225    * <p>
226    * If the interval object is <code>null</code>, or the interval's chronology is
227    * <code>null</code>, {@link ISOChronology#getInstance()} will be returned.
228    * Otherwise, the chronology from the object is returned.
229    *
230    * @param interval the interval to examine, null means ISO in the default zone
231    * @return the chronology, never null
232    */
 
233  4 toggle public static final Chronology getIntervalChronology(ReadableInterval interval) {
234  4 if (interval == null) {
235  1 return ISOChronology.getInstance();
236    }
237  3 Chronology chrono = interval.getChronology();
238  3 if (chrono == null) {
239  1 return ISOChronology.getInstance();
240    }
241  2 return chrono;
242    }
243   
244    //-----------------------------------------------------------------------
245   
246    /**
247    * Gets the interval handling null.
248    * <p>
249    * If the interval is <code>null</code>, an interval representing now
250    * to now in the {@link ISOChronology#getInstance() ISOChronology}
251    * will be returned. Otherwise, the interval specified is returned.
252    *
253    * @param interval the interval to use, null means now to now
254    * @return the interval, never null
255    * @since 1.1
256    */
 
257  86 toggle public static final ReadableInterval getReadableInterval(ReadableInterval interval) {
258  86 if (interval == null) {
259  14 long now = DateTimeUtils.currentTimeMillis();
260  14 interval = new Interval(now, now);
261    }
262  86 return interval;
263    }
264   
265    //-----------------------------------------------------------------------
266   
267    /**
268    * Gets the chronology handling null.
269    * <p>
270    * If the chronology is <code>null</code>, {@link ISOChronology#getInstance()}
271    * will be returned. Otherwise, the chronology is returned.
272    *
273    * @param chrono the chronology to use, null means ISO in the default zone
274    * @return the chronology, never null
275    */
 
276  460063 toggle public static final Chronology getChronology(Chronology chrono) {
277  460063 if (chrono == null) {
278  13051 return ISOChronology.getInstance();
279    }
280  447012 return chrono;
281    }
282   
283    //-----------------------------------------------------------------------
284   
285    /**
286    * Gets the zone handling null.
287    * <p>
288    * If the zone is <code>null</code>, {@link DateTimeZone#getDefault()}
289    * will be returned. Otherwise, the zone specified is returned.
290    *
291    * @param zone the time zone to use, null means the default zone
292    * @return the time zone, never null
293    */
 
294  30045 toggle public static final DateTimeZone getZone(DateTimeZone zone) {
295  30045 if (zone == null) {
296  27 return DateTimeZone.getDefault();
297    }
298  30018 return zone;
299    }
300   
301    //-----------------------------------------------------------------------
302   
303    /**
304    * Gets the period type handling null.
305    * <p>
306    * If the zone is <code>null</code>, {@link PeriodType#standard()}
307    * will be returned. Otherwise, the type specified is returned.
308    *
309    * @param type the time zone to use, null means the standard type
310    * @return the type to use, never null
311    */
 
312  39470 toggle public static final PeriodType getPeriodType(PeriodType type) {
313  39470 if (type == null) {
314  205 return PeriodType.standard();
315    }
316  39265 return type;
317    }
318   
319    //-----------------------------------------------------------------------
320   
321    /**
322    * Gets the millisecond duration from the specified duration object handling null.
323    * <p>
324    * If the duration object is <code>null</code>, zero will be returned.
325    * Otherwise, the millis from the object are returned.
326    *
327    * @param duration the duration to examine, null means zero
328    * @return the duration in milliseconds
329    */
 
330  65 toggle public static final long getDurationMillis(ReadableDuration duration) {
331  65 if (duration == null) {
332  22 return 0L;
333    }
334  43 return duration.getMillis();
335    }
336   
337    //-----------------------------------------------------------------------
338   
339    /**
340    * Checks whether the partial is contiguous.
341    * <p>
342    * A partial is contiguous if one field starts where another ends.
343    * <p>
344    * For example <code>LocalDate</code> is contiguous because DayOfMonth has
345    * the same range (Month) as the unit of the next field (MonthOfYear), and
346    * MonthOfYear has the same range (Year) as the unit of the next field (Year).
347    * <p>
348    * Similarly, <code>LocalTime</code> is contiguous, as it consists of
349    * MillisOfSecond, SecondOfMinute, MinuteOfHour and HourOfDay (note how
350    * the names of each field 'join up').
351    * <p>
352    * However, a Year/HourOfDay partial is not contiguous because the range
353    * field Day is not equal to the next field Year.
354    * Similarly, a DayOfWeek/DayOfMonth partial is not contiguous because
355    * the range Month is not equal to the next field Day.
356    *
357    * @param partial the partial to check
358    * @return true if the partial is contiguous
359    * @throws IllegalArgumentException if the partial is null
360    * @since 1.1
361    */
 
362  216 toggle public static final boolean isContiguous(ReadablePartial partial) {
363  216 if (partial == null) {
364  2 throw new IllegalArgumentException("Partial must not be null");
365    }
366  214 DurationFieldType lastType = null;
367  805 for (int i = 0; i < partial.size(); i++) {
368  600 DateTimeField loopField = partial.getField(i);
369  600 if (i > 0) {
370  386 if (loopField.getRangeDurationField() == null || loopField.getRangeDurationField().getType() != lastType) {
371  9 return false;
372    }
373    }
374  591 lastType = loopField.getDurationField().getType();
375    }
376  205 return true;
377    }
378   
379    //-----------------------------------------------------------------------
380   
381    /**
382    * Gets the {@link DateFormatSymbols} based on the given locale.
383    * <p>
384    * If JDK 6 or newer is being used, DateFormatSymbols.getInstance(locale) will
385    * be used in order to allow the use of locales defined as extensions.
386    * Otherwise, new DateFormatSymbols(locale) will be used.
387    * See JDK 6 {@link DateFormatSymbols} for further information.
388    *
389    * @param locale the {@link Locale} used to get the correct {@link DateFormatSymbols}
390    * @return the symbols
391    * @since 2.0
392    */
 
393  7 toggle public static final DateFormatSymbols getDateFormatSymbols(Locale locale) {
394  7 try {
395  7 Method method = DateFormatSymbols.class.getMethod("getInstance", new Class[]{Locale.class});
396  7 return (DateFormatSymbols) method.invoke(null, new Object[]{locale});
397    } catch (Exception ex) {
398  0 return new DateFormatSymbols(locale);
399    }
400    }
401   
402    //-----------------------------------------------------------------------
403   
404    /**
405    * Gets the default map of time zone names.
406    * <p>
407    * This can be changed by {@link #setDefaultTimeZoneNames}.
408    * <p>
409    * The default set of short time zone names is as follows:
410    * <ul>
411    * <li>UT - UTC
412    * <li>UTC - UTC
413    * <li>GMT - UTC
414    * <li>EST - America/New_York
415    * <li>EDT - America/New_York
416    * <li>CST - America/Chicago
417    * <li>CDT - America/Chicago
418    * <li>MST - America/Denver
419    * <li>MDT - America/Denver
420    * <li>PST - America/Los_Angeles
421    * <li>PDT - America/Los_Angeles
422    * </ul>
423    *
424    * @return the unmodifiable map of abbreviations to zones, not null
425    * @since 2.2
426    */
 
427  0 toggle public static final Map<String, DateTimeZone> getDefaultTimeZoneNames() {
428  0 Map<String, DateTimeZone> names = cZoneNames.get();
429  0 if (names == null) {
430  0 names = buildDefaultTimeZoneNames();
431  0 if (!cZoneNames.compareAndSet(null, names)) {
432  0 names = cZoneNames.get();
433    }
434    }
435  0 return names;
436    }
437   
438    /**
439    * Sets the default map of time zone names.
440    * <p>
441    * The map is copied before storage.
442    *
443    * @param names the map of abbreviations to zones, not null
444    * @since 2.2
445    */
 
446  0 toggle public static final void setDefaultTimeZoneNames(Map<String, DateTimeZone> names) {
447  0 cZoneNames.set(Collections.unmodifiableMap(new HashMap<String, DateTimeZone>(names)));
448    }
449   
 
450  0 toggle private static Map<String, DateTimeZone> buildDefaultTimeZoneNames() {
451    // names from RFC-822 / JDK
452    // this is all very US-centric and dubious, but perhaps it will help some
453  0 Map<String, DateTimeZone> map = new LinkedHashMap<String, DateTimeZone>();
454  0 map.put("UT", DateTimeZone.UTC);
455  0 map.put("UTC", DateTimeZone.UTC);
456  0 map.put("GMT", DateTimeZone.UTC);
457  0 put(map, "EST", "America/New_York");
458  0 put(map, "EDT", "America/New_York");
459  0 put(map, "CST", "America/Chicago");
460  0 put(map, "CDT", "America/Chicago");
461  0 put(map, "MST", "America/Denver");
462  0 put(map, "MDT", "America/Denver");
463  0 put(map, "PST", "America/Los_Angeles");
464  0 put(map, "PDT", "America/Los_Angeles");
465  0 return Collections.unmodifiableMap(map);
466    }
467   
 
468  0 toggle private static void put(Map<String, DateTimeZone> map, String name, String id) {
469  0 try {
470  0 map.put(name, DateTimeZone.forID(id));
471    } catch (RuntimeException ex) {
472    // ignore
473    }
474    }
475    //-------------------------------------------------------------------------
476   
477    /**
478    * Calculates the astronomical Julian Day for an instant.
479    * <p>
480    * The <a href="https://en.wikipedia.org/wiki/Julian_day">Julian day</a> is a well-known
481    * system of time measurement for scientific use by the astronomy community.
482    * It expresses the interval of time in days and fractions of a day since
483    * January 1, 4713 BC (Julian) Greenwich noon.
484    * <p>
485    * Each day starts at midday (not midnight) and time is expressed as a fraction.
486    * Thus the fraction 0.25 is 18:00. equal to one quarter of the day from midday to midday.
487    * <p>
488    * Note that this method has nothing to do with the day-of-year.
489    *
490    * @param epochMillis the epoch millis from 1970-01-01Z
491    * @return the astronomical Julian Day represented by the specified instant
492    * @since 2.2
493    */
 
494  16 toggle public static final double toJulianDay(long epochMillis) {
495    // useful links
496    // https://en.wikipedia.org/wiki/Julian_day#cite_note-13 - Wikipedia
497    // http://aa.usno.navy.mil/data/docs/JulianDate.php" - USNO
498    // http://users.zoominternet.net/~matto/Java/Julian%20Date%20Converter.htm - Julian Date Converter by Matt Oltersdorf
499    // http://ssd.jpl.nasa.gov/tc.cgi#top - CalTech
500  16 double epochDay = epochMillis / 86400000d;
501  16 return epochDay + 2440587.5d;
502    }
503   
504    /**
505    * Calculates the astronomical Julian Day Number for an instant.
506    * <p>
507    * The {@link #toJulianDay(long)} method calculates the astronomical Julian Day
508    * with a fraction based on days starting at midday.
509    * This method calculates the variant where days start at midnight.
510    * JDN 0 is used for the date equivalent to Monday January 1, 4713 BC (Julian).
511    * Thus these days start 12 hours before those of the fractional Julian Day.
512    * <p>
513    * Note that this method has nothing to do with the day-of-year.
514    *
515    * @param epochMillis the epoch millis from 1970-01-01Z
516    * @return the astronomical Julian Day represented by the specified instant
517    * @since 2.2
518    */
 
519  8 toggle public static final long toJulianDayNumber(long epochMillis) {
520  8 return (long) Math.floor(toJulianDay(epochMillis) + 0.5d);
521    }
522   
523    /**
524    * Creates a date-time from a Julian Day.
525    * <p>
526    * Returns the {@code DateTime} object equal to the specified Julian Day.
527    *
528    * @param julianDay the Julian Day
529    * @return the epoch millis from 1970-01-01Z
530    * @since 2.2
531    */
 
532  7 toggle public static final long fromJulianDay(double julianDay) {
533  7 double epochDay = julianDay - 2440587.5d;
534  7 return (long) (epochDay * 86400000d);
535    }
536   
537    //-----------------------------------------------------------------------
538   
539    /**
540    * A millisecond provider, allowing control of the system clock.
541    *
542    * @author Stephen Colebourne
543    * @since 2.0 (previously private)
544    */
 
545    public static interface MillisProvider {
546    /**
547    * Gets the current time.
548    * <p>
549    * Implementations of this method must be thread-safe.
550    *
551    * @return the current time in milliseconds
552    */
553    long getMillis();
554    }
555   
556    /**
557    * System millis provider.
558    */
 
559    static class SystemMillisProvider implements MillisProvider {
560    /**
561    * Gets the current time.
562    *
563    * @return the current time in millis
564    */
 
565  10133 toggle public long getMillis() {
566  10133 return System.currentTimeMillis();
567    }
568    }
569   
570    /**
571    * Fixed millisecond provider.
572    */
 
573    static class FixedMillisProvider implements MillisProvider {
574    /**
575    * The fixed millis value.
576    */
577    private final long iMillis;
578   
579    /**
580    * Constructor.
581    *
582    * @param fixedMillis the millis value
583    */
 
584  3072 toggle FixedMillisProvider(long fixedMillis) {
585  3072 iMillis = fixedMillis;
586    }
587   
588    /**
589    * Gets the current time.
590    *
591    * @return the current time in millis
592    */
 
593  468 toggle public long getMillis() {
594  468 return iMillis;
595    }
596    }
597   
598    /**
599    * Offset from system millis provider.
600    */
 
601    static class OffsetMillisProvider implements MillisProvider {
602    /**
603    * The millis offset.
604    */
605    private final long iMillis;
606   
607    /**
608    * Constructor.
609    *
610    * @param offsetMillis the millis offset
611    */
 
612  1 toggle OffsetMillisProvider(long offsetMillis) {
613  1 iMillis = offsetMillis;
614    }
615   
616    /**
617    * Gets the current time.
618    *
619    * @return the current time in millis
620    */
 
621  1 toggle public long getMillis() {
622  1 return System.currentTimeMillis() + iMillis;
623    }
624    }
625   
626    }